
package com.wuye.services.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.wuye.common.exception.RtManagerException;
import com.wuye.common.services.impl.BaseManagerImpl;
import com.wuye.common.util.bean.EntityCopyUtil;
import com.wuye.common.util.numeric.NumericUtil;
import com.wuye.common.util.string.StrUtil;
import com.wuye.common.vo.PageInfo;
import com.wuye.common.vo.RetVO;
import com.wuye.constants.BaseConstants;
import com.wuye.dao.CommunityDao;
import com.wuye.dao.PropertyCompanyDao;
import com.wuye.dao.UserDao;
import com.wuye.entity.Address;
import com.wuye.entity.Area;
import com.wuye.entity.Organization;
import com.wuye.entity.PartyInfo;
import com.wuye.entity.Privilege;
import com.wuye.entity.PropertyCompany;
import com.wuye.entity.Role;
import com.wuye.entity.User;
import com.wuye.entity.UserAuth;
import com.wuye.entity.UserOrgRel;
import com.wuye.services.UserServiceManager;

@Service("userServiceManager")
public class UserServiceManagerImpl extends BaseManagerImpl implements UserServiceManager {

	@Autowired
	private UserDao userDao;
	@Autowired
	private CommunityDao communityDao;
	@Autowired
	private PropertyCompanyDao propertyCompanyDao;
	
	public void saveUser(Map<String, Object> map) {
		// TODO Auto-generated method stub
		User user = (User)map.get("user");
		Address address = null;//地址取物业公司上的
		if  (map.containsKey("proertyCompany")) {
			PropertyCompany propertyCompany = (PropertyCompany)map.get("proertyCompany");
			//物业公司直接保存在用户上，不保存物业公司与用户的关系
			user.setOwnerCompany(propertyCompany);
			
			if (propertyCompany.getCompanyInfo() != null){
				address = propertyCompany.getCompanyInfo().getAddress();
			}
		}
		user.save();
		
		/*if (map.containsKey("area") && map.containsKey("address")) {
			Area area = (Area) map.get("area");
			address = (Address) map.get("address");
			address.setArea(area);
			address.save();
		} else {
			address = new Address();
		}*/
		if (map.containsKey("partyInfo")) {			
			PartyInfo partyInfo = (PartyInfo)map.get("partyInfo");
			partyInfo.setClassId(BaseConstants.CLASS_USER);			//表示用户
			partyInfo.setObjId(user.getId());
			partyInfo.setStatusCd(user.getStatusCd());
			partyInfo.setMobile(user.getAccount());
			partyInfo.setAddress(address);
			partyInfo.save();
		}
		if (map.containsKey("roleList")) {			
			List<Role> roleList = (List<Role>)map.get("roleList");
			for (Role role : roleList) {
				UserAuth userAuth = new UserAuth();
				userAuth.setRole(role);
				userAuth.setUser(user);
				userAuth.setStatusCd("1000");
				userAuth.save();
			}
		}
		if (map.containsKey("orgList")) {	
			List<UserOrgRel> userOrgs = new ArrayList<UserOrgRel>(user.getUserOrgRels());;
			JSONArray orgArray = (JSONArray)map.get("orgList");
			if (userOrgs != null && userOrgs.size() > 0){
				for (int i = 0; i < userOrgs.size(); i++){
					UserOrgRel org = userOrgs.get(i);
					boolean isRemove = true;
					for (int j = 0; j < orgArray.size(); j++) {
						if (org.getOrganization().getId().equals(orgArray.getInt(j))){
							isRemove = false;
							break;
						}
					}
					if (isRemove){
						//删除的单位关联
						org.remove();
					}
				}
			}
			for (int j = 0; j < orgArray.size(); j++) {
				boolean isAdd = true;
				for (int i = 0; i < userOrgs.size(); i++){
					if (userOrgs.get(i).getOrganization().getId().equals(orgArray.getInt(j))){
						isAdd = false;
					}
				}
				if (isAdd){
					Organization org=(Organization) Organization.getDefaultDao().getObject(Organization.class, orgArray.getInt(j));
					UserOrgRel userOrgRel = new UserOrgRel();
					userOrgRel.setUser(user);
					userOrgRel.setOrganization(org);
					userOrgRel.save();
				}
			}
		}
		/*if (map.containsKey("cmmunity")) {
			Community community = (Community)map.get("cmmunity");
			community = (Community)communityDao.getObject(Community.class, community.getId());
			if (!StrUtil.isNullOrEmpty(community) && !StrUtil.isNullOrEmpty(community.getOrganization())
					&& !StrUtil.isNullOrEmpty(community.getOrganization().getId())) {
				UserOrgRel userOrgRel = new UserOrgRel();
				userOrgRel.setUser(user);
				userOrgRel.setOrganization(community.getOrganization());
				userOrgRel.save();
			}
		} else if (map.containsKey("proertyCompany")){
			PropertyCompany propertyCompany = (PropertyCompany)map.get("proertyCompany");
			propertyCompany = (PropertyCompany)propertyCompanyDao.getObject(PropertyCompany.class, propertyCompany.getId());
			if (!StrUtil.isNullOrEmpty(propertyCompany) && !StrUtil.isNullOrEmpty(propertyCompany.getOrganization())
					&& !StrUtil.isNullOrEmpty(propertyCompany.getOrganization().getId())) {
				UserOrgRel userOrgRel = new UserOrgRel();
				userOrgRel.setUser(user);
				userOrgRel.setOrganization(propertyCompany.getOrganization());
				userOrgRel.save();
			}
		}*/
	}

	public boolean isExitAccount(String account) {
		User user = userDao.getUserByAccount(account);
		if (user != null) {
			return true;
		}
		return false;
	}

	public RetVO getUser(Map<String, Object> map,
			final int currentPage, final int perPageNum) {
		RetVO retVO = RetVO.newInstance(BaseConstants.RET_TRUE, "");
		PageInfo pg = userDao.getUser(map, currentPage, perPageNum);
		List<Object> dataList = pg.getDataList();
		JSONArray jsArray = new JSONArray();
		if (dataList != null && dataList.size() > 0){
			for (Object obj : dataList){
				User user = (User)obj;
				PartyInfo partyInfo = user.getPartyInfo() ;
				JSONObject jsobj = EntityCopyUtil.getJSONObject(user,null);
				if (partyInfo != null){
					Address srcAddr = partyInfo.getAddress();
					JSONObject partyJson = EntityCopyUtil.getJSONObject(partyInfo,new String[]{"partyInfoId","partyName","qq","weiXin","email"});
					if (srcAddr != null){
						JSONObject addr = EntityCopyUtil.getJSONObject(srcAddr , null);
						Area area = srcAddr.getArea();
						Area city = area.getUpArea();
						Area province = city.getUpArea();
						JSONObject jsarea = EntityCopyUtil.getJSONObject(area, null);
						JSONObject jsCity = EntityCopyUtil.getJSONObject(city, null);
						JSONObject jsProvince = EntityCopyUtil.getJSONObject(province, null);
						jsCity.put("upArea", jsProvince);
						jsarea.put("upArea", jsCity);
						addr.put("area", jsarea);
						partyJson.put("address", addr);
					}
					jsobj.put("partyInfo", partyJson);
				}
				PropertyCompany company = user.getOwnerCompany();
				jsobj.put("company", EntityCopyUtil.getJSONObject(company,new String[]{"companyId","companyName"}));
				
				List<Role> roles = user.getRoles();
				if (roles != null && roles.size() > 0){
					JSONArray roleJsArray = new JSONArray();
					for (Role role : roles){
						JSONObject roleJsobj = EntityCopyUtil.getJSONObject(role,new String[]{"roleId","roleName"});
						roleJsArray.add(roleJsobj);
					}
					jsobj.put("roles", roleJsArray);
				}
				jsArray.add(jsobj);
			}
		}
		retVO.setObject(jsArray);
		return retVO;
	}

	public User getUserBindingsWeiXin(String opendId) {
		List<User> userList = userDao.getUserByOpendId(opendId);
		if (userList != null && userList.size() > 0) {
			return userList.get(0);
		}
		return null;
	}

	public boolean updateUserOpendId(User user) {
		User oldUser = userDao.getUserByAccount(user.getAccount());
		if (oldUser != null) {
			oldUser.setOpendId(user.getOpendId());
			oldUser.setOpendTime(user.getOpendTime());
			oldUser.save();
			return true;
		}
		return false;
	}

	public User getUserByAccount(String account) {
		return userDao.getUserByAccount(account);
	}
	/**
	 * {@inheritDoc}
	 * @see com.wuye.services.UserServiceManager#qryUserList(java.util.Map, int, int)
	 * @author Luxb
	 * 2015-12-19 Luxb
	 */
    public PageInfo qryUserList(Map<String, Object> map, int currentPage, int perPageNum) {
        return userDao.getUser(map, currentPage, perPageNum);
    }

    public RetVO del(Map<String, Object> map) throws Exception {
        RetVO retVo = RetVO.newInstance(BaseConstants.RET_TRUE, "权限删除成功!");
        
        JSONArray users = (JSONArray) map.get("userIdArray");
        if (users != null && users.size() > 0) {
            for (int i = 0; i < users.size(); i++) {
                String[] str = users.getString(i).split(";");
                int userId = NumericUtil.toInt(str[0]);
                /*int partyId = NumericUtil.toInt(str[1]);
                int addressId = NumericUtil.toInt(str[2]);*/
                User user = (User) User.getDefaultDao().getObject(User.class, userId);
                if (user != null){
                	//删除关联组织信息
                	List<UserOrgRel> userOrgs = new ArrayList<UserOrgRel>(user.getUserOrgRels());
                	if (userOrgs != null){
                		for (int j = 0; j < userOrgs.size(); j++){
                			userOrgs.get(j).remove();
                		}
                	}
                	//删除关联的授权信息
                	List<UserAuth> userAuths = new ArrayList<UserAuth>(user.getUserAuths());
                	if (userAuths != null){
                		for (int j = 0; j < userAuths.size(); j++){
                			userAuths.get(j).remove();
                		}
                	}
                	//删除用户信息
                	PartyInfo partyInfo = user.getPartyInfo();
                	if (partyInfo != null){
                		Address address = partyInfo.getAddress();
                		if (address != null){
                			address.remove();
                		}
                		partyInfo.remove();
                	}
                	user.remove();
                }
            }
        }

        return retVo;
    }
    
    public RetVO getOrgs(Map<String, Object> map){
    	RetVO retVo = RetVO.newInstance(BaseConstants.RET_TRUE, "查询成功");
    	
    	if (map.get("companyId") != null){
    		//查询物业公司的所有下级组织
    		Integer companyId = NumericUtil.nullToIntegerZero(map.get("companyId"));
    		PropertyCompany company = (PropertyCompany) PropertyCompany.getDao().getObject(PropertyCompany.class, companyId);
    		if (company != null){
    			Organization rootOrg = company.getOrganization();
    			if (rootOrg != null){
    				List<Organization> orgs = rootOrg.getAllChild();
    				if (orgs != null && orgs.size() > 0){
    					orgs.add(0, rootOrg);
    					retVo.setObject(orgs);
    					return retVo;
    				}
    			}else{
    				return retVo;
    			}
    		}else{
    			return retVo;
    		}
    	}else if (map.get("userId") != null){
    		//获取用户关联的组织
    		Integer userId = NumericUtil.nullToIntegerZero(map.get("userId"));
    		User user = (User) User.getDefaultDao().getObject(User.class, userId);
    		if (user != null){
    			List<Organization> orgs = user.getOrgs();
    			if (orgs != null && orgs.size() > 0){
    				retVo.setObject(orgs);
    				return retVo;
    			}
    		}
    	}
    	return retVo;
    }
    public RetVO getRoles(Map<String, Object> map){
    	RetVO retVo = RetVO.newInstance(BaseConstants.RET_TRUE, "查询成功");
    	
    	if (map.get("userId") != null){
    		//获取用户关联的组织
    		Integer userId = NumericUtil.nullToIntegerZero(map.get("userId"));
    		User user = (User) User.getDefaultDao().getObject(User.class, userId);
    		if (user != null){
    			List<Role> roles = user.getRoles();
    			if (roles != null && roles.size() > 0){
    				JSONArray jsArray = new JSONArray();
    				for (Role com : roles){
						JSONObject jsObj = EntityCopyUtil.getJSONObject(com,new String[]{"roleId","roleName"});
						jsArray.add(jsObj);
					}
    				retVo.setObject(jsArray);
    				return retVo;
    			}
    		}
    	}
    	return retVo;
    }

    public RetVO save(Map<String, Object> map) throws Exception {
		RetVO retVo = RetVO.newInstance(BaseConstants.RET_TRUE, "");
		//String type = (String) map.get("type");
		JSONArray users = (JSONArray) map.get("user");
		String type = StrUtil.strnull(map.get("type"));
		if (users != null && users.size() > 0) {
			for (int i = 0; i < users.size(); i++) {
				JSONObject srcUser = users.getJSONObject(i);
				if ("savePrivilege".equals(type)){
					this.savePrivilege(srcUser);
				}else{
					User existUser = userDao.getUserByAccount(StrUtil.strnull(srcUser.getString("account")));
					
					if (StrUtil.isNullOrEmpty(srcUser.get("userId"))) {
						if (existUser != null){
							throw new RtManagerException("用户已存在");
						}
						// 新增
						this.add(srcUser);
					} else {
						if (existUser != null && !existUser.getId().equals(srcUser.getInt("userId"))){
							throw new RtManagerException("用户已存在");
						}
						// 更改
						this.update(srcUser);
					}
				}
				
			}
		}

		return retVo;
	}

	private void savePrivilege(JSONObject srcUser) {
		int userId = srcUser.getInt("userId");
		User user = (User) User.getDao().getObject(User.class, userId);
		JSONArray userAuth = null;
		if (srcUser.get("userAuth") instanceof JSONArray){
			//srcUser.get("userAuth") 为空的时候就不是JSONArray了
			userAuth = srcUser.getJSONArray("userAuth");
		}
		this.saveUserAuths(user, false, "privilege",userAuth) ;
	}

	public RetVO update(JSONObject srcUser) {
		User user = (User)User.getDefaultDao().getObject(User.class, srcUser.getInt("userId"));
		//用户信息
		String oldPwd = user.getPwd();
		EntityCopyUtil.populate(user, srcUser, null);
		PropertyCompany propertyCompany = (PropertyCompany) PropertyCompany.getDao().getObject(PropertyCompany.class, 
				srcUser.getJSONObject("propertyCompany").getInt("companyId"));
		
		PartyInfo userInfo = user.getPartyInfo();
		if (userInfo == null){
			userInfo = new PartyInfo();
			Address add = new Address();
			userInfo.setAddress(add);
			user.setPartyInfo(userInfo);
		}
		Address add = userInfo.getAddress();
		
		if (propertyCompany.getCompanyInfo() != null
				&& propertyCompany.getCompanyInfo().getAddress() != null){
			add.setArea(propertyCompany.getCompanyInfo().getAddress().getArea());
			
		}
		EntityCopyUtil.populate(add, srcUser.getJSONObject("partyInfo")
				.getJSONObject("address"), null);
		
		EntityCopyUtil.populate(userInfo,
				srcUser.getJSONObject("partyInfo"), null);
		userInfo.setMobile(user.getAccount());
		user.setOwnerCompany(propertyCompany);
		if (StrUtil.isNullOrEmpty(user.getPwd())){
			if (StrUtil.isNullOrEmpty(oldPwd)){
				user.setPwd("123123");
			}else{
				user.setPwd(oldPwd);
			}
		}
		
		//单位信息
		JSONArray srcOrgs = srcUser.getJSONArray("userOrgRel");
		JSONArray srcAuths = srcUser.getJSONArray("userAuth");
		//保存用户信息
		user.save();
		//保存单位信息
		saveUserOrgs(true,user,srcOrgs);
		//保存角色权限信息
		saveUserAuths(user,false,"role", srcAuths);
		
		return null;
	}

	public RetVO add(JSONObject srcUser) {
		User user = new User();
		//用户信息
		EntityCopyUtil.populate(user, srcUser, null);
		PropertyCompany propertyCompany = (PropertyCompany) PropertyCompany.getDao().getObject(PropertyCompany.class, 
				srcUser.getJSONObject("propertyCompany").getInt("companyId"));
		Address add = new Address();
		
		if (propertyCompany.getCompanyInfo() != null
				&& propertyCompany.getCompanyInfo().getAddress() != null){
			add.setArea(propertyCompany.getCompanyInfo().getAddress().getArea());
			
		}
		EntityCopyUtil.populate(add, srcUser.getJSONObject("partyInfo")
				.getJSONObject("address"), null);
		
		PartyInfo userInfo = new PartyInfo();
		EntityCopyUtil.populate(userInfo,
				srcUser.getJSONObject("partyInfo"), null);
		
		userInfo.setAddress(add);
		userInfo.setMobile(user.getAccount());
		user.setPartyInfo(userInfo);
		user.setOwnerCompany(propertyCompany);
		user.setPwd("123123");
		//单位信息
		JSONArray srcOrgs = srcUser.getJSONArray("userOrgRel");
		JSONArray srcAuths = srcUser.getJSONArray("userAuth");
		//保存用户信息
		user.save();
		//保存单位信息
		saveUserOrgs(true,user,srcOrgs);
		//保存角色权限信息
		saveUserAuths(user,true,"role", srcAuths);
		
		return null;
	}
	
	/**
	 * 设置用户的组织
	 * @param isAdd
	 * @param user
	 * @param srcOrgs
	 */
	private void saveUserOrgs(boolean isNew, User user,JSONArray srcOrgs){
		if (srcOrgs == null || user == null || srcOrgs.size() < 1){
			return ;
		}
		if (isNew){
			for (int i = 0; i < srcOrgs.size(); i++){
				Organization org=(Organization) Organization.getDefaultDao().getObject(Organization.class, srcOrgs.getJSONObject(i).getInt("orgId"));
				if (org != null){
					UserOrgRel userOrgRel = new UserOrgRel();
					userOrgRel.setUser(user);
					userOrgRel.setOrganization(org);
					userOrgRel.save();
				}
			}
		}else{
			//用户已有的组织
			List<UserOrgRel> userOrgs = new ArrayList<UserOrgRel>(user.getUserOrgRels());;
			
			//删除旧的
			if ( userOrgs != null && userOrgs.size() > 0){
				for (UserOrgRel userOrg : userOrgs){
					userOrg.remove();
				}
			}
			//新增新的
			this.saveUserOrgs(true, user, srcOrgs);
			/*if (userOrgs != null && userOrgs.size() > 0){
				for (int i = 0; i < userOrgs.size(); i++){
					UserOrgRel org = userOrgs.get(i);
					boolean isRemove = true;
					for (int j = 0; j < srcOrgs.size(); j++) {
						if (org.getOrganization().getId().equals(srcOrgs.getJSONObject(j).getInt("orgId"))){
							isRemove = false;
							break;
						}
					}
					if (isRemove){
						//需要删除的
						org.remove();
					}
				}
			}
			for (int j = 0; j < srcOrgs.size(); j++) {
				boolean isAdd = true;
				for (int i = 0; i < userOrgs.size(); i++){
					if (userOrgs.get(i).getOrganization().getId().equals(srcOrgs.getJSONObject(j).getInt("orgId"))){
						isAdd = false;
					}
				}
				if (isAdd){
					//需要新增的
					Organization org=(Organization) Organization.getDefaultDao().getObject(Organization.class, srcOrgs.getJSONObject(j).getInt("orgId"));
					if (org != null){
						UserOrgRel userOrgRel = new UserOrgRel();
						userOrgRel.setUser(user);
						userOrgRel.setOrganization(org);
						userOrgRel.save();
					}
				}
			}*/
		}
	}
	/**
	 * 设置用户的组织
	 * @param user
	 * @param type TODO
	 * @param isAdd
	 * @param srcOrgs
	 */
	private void saveUserAuths(User user, boolean isNew,String type, JSONArray srcUserAuths){
		if (user == null){
			return ;
		}
		if (isNew){
			if (srcUserAuths == null || srcUserAuths.size() < 1){
				return;
			}
			for (int i = 0; i < srcUserAuths.size(); i++){
				String roleId = StrUtil.strnull(srcUserAuths.getJSONObject(i).get("roleId"));
				String privilegeId = StrUtil.strnull(srcUserAuths.getJSONObject(i).get("privilegeId"));
				
				//权限
				if (!StrUtil.isNullOrEmpty(privilegeId)){
					Privilege privilege = (Privilege) Privilege.getDefaultDao().getObject(Privilege.class, Integer.valueOf(privilegeId));
					UserAuth auth = new UserAuth();
					auth.setUser(user);
					auth.setPrivilege(privilege);
					auth.save();
				}else if (!StrUtil.isNullOrEmpty(roleId)){
					//角色
					Role role = (Role) Privilege.getDefaultDao().getObject(Role.class, Integer.valueOf(roleId));
					UserAuth auth = new UserAuth();
					auth.setRole(role);
					auth.setUser(user);
					auth.save();
				}
			}
		}else{
			//用户已有的组织
			List<UserAuth> userAuths = new ArrayList<UserAuth>(user.getUserAuths());;
			
			//删除旧的
			if (userAuths != null && userAuths.size() > 0){
				for (UserAuth userAuth : userAuths){
					if ("role".equals(type) && userAuth.getRole() != null){
						//删除旧的角色授权信息
						userAuth.remove();
					}
					if ("privilege".equals(type) && userAuth.getPrivilege() != null){
						//删除权限的授权信息
						userAuth.remove();
					}
					
				}
			}
			//增加新的
			this.saveUserAuths(user, true, type, srcUserAuths);
		}
	}

	public RetVO hasPrivilege(User user,String... privilegeCode){
		RetVO ret = RetVO.newInstance();
		if (user == null || privilegeCode == null || privilegeCode.length < 1){
			return null;
		}
		JSONArray jsarray = new JSONArray();
		Map<String,String> retMap = new HashMap<String,String>();
		for (String each : privilegeCode){
			JSONObject jsobj = new JSONObject();
			jsobj.put("code", each);
			jsobj.put("value", user.hasPrivilege(each) == true ? "1" : "0");
			jsarray.add(jsobj);
		}
		ret.setObject(jsarray);
		return ret;
	}
	
	public RetVO getPrivileges(Map<String, Object> map){
    	RetVO retVo = RetVO.newInstance(BaseConstants.RET_TRUE, "查询成功");
    	
    	if (map.get("userId") != null){
    		//获取用户关联的组织
    		Integer userId = NumericUtil.nullToIntegerZero(map.get("userId"));
    		User user = (User) User.getDefaultDao().getObject(User.class, userId);
    		if (user != null){
    			List<Privilege> privileges ;
    			if (!StrUtil.isNullOrEmpty(map.get("isDirect")) && "1".equals(map.get("isDirect"))){
    				privileges = user.getDirectPrivileges();
    			}else{
    				privileges = user.getPrivileges();
    			}
    			
    			if (privileges != null && privileges.size() > 0){
    				retVo.setObject(privileges);
    				return retVo;
    			}
    		}
    	}
    	return retVo;
    }
}
